package com.yt.lxh.product.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yt.lxh.common.exception.ServiceException;
import com.yt.lxh.common.result.ResultCodeEnum;
import com.yt.lxh.common.service.MinioService;
import com.yt.lxh.common.utils.AuthContextUtil;
import com.yt.lxh.constant.MQConst;
import com.yt.lxh.constant.ProductConstant;
import com.yt.lxh.constant.SQLConstant;
import com.yt.lxh.model.acl.Admin;
import com.yt.lxh.vo.product.SimpleSkuVO;
import com.yt.lxh.vo.product.SkuVO;
import com.yt.lxh.model.product.SkuDetail;
import com.yt.lxh.model.product.SkuInfo;
import com.yt.lxh.dto.product.SaveSkuDTO;
import com.yt.lxh.dto.product.UpdateSkuDTO;
import com.yt.lxh.mq.service.RabbitService;
import com.yt.lxh.product.mapper.SkuDetailMapper;
import com.yt.lxh.product.mapper.SkuInfoMapper;
import com.yt.lxh.product.service.SkuService;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.core.MessageDeliveryMode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author yzk789
 * @since 2023-10-18
 */
@Service
@Transactional
public class SkuServiceImpl extends ServiceImpl<SkuInfoMapper, SkuInfo> implements SkuService {

    @Autowired
    private SkuInfoMapper skuInfoMapper;

    @Autowired
    private SkuDetailMapper skuDetailMapper;

    @Autowired
    private MinioService minioService;

    @Autowired
    private RabbitService rabbitService;

    /**
     * 根据类别ID 获取商品信息
     * @param categoryId
     * @return
     */
    @Override
    public List<SimpleSkuVO> simpleSkuListByCategoryId(String categoryId) {
        if (StrUtil.isBlank(categoryId)) throw new ServiceException(ResultCodeEnum.PARAM_REQUIRE);
        LambdaQueryWrapper<SkuInfo> wrapper = Wrappers.<SkuInfo>lambdaQuery()
                .select(SkuInfo::getId, SkuInfo::getSkuName, SkuInfo::getSkuImg,
                        SkuInfo::getPrice, SkuInfo::getOnSale, SkuInfo::getCategoryId ,SkuInfo::getSort)
                .eq(SkuInfo::getCategoryId, categoryId)
                .orderByDesc(SkuInfo::getOnSale);
        List<SkuInfo> skuInfos = skuInfoMapper.selectList(wrapper);
        if(skuInfos == null && skuInfos.size() == 0) return null;
        return BeanUtil.copyToList(skuInfos, SimpleSkuVO.class);
    }

    /**
     * 保存商品
     * @param saveSkuDTO
     */
    @Override
    public void saveSku(SaveSkuDTO saveSkuDTO) {
        // 获取用户信息
//        Admin admin = AuthContextUtil.get();
        final Admin admin = new Admin();
        admin.setUsername("测试");
        // 处理数据，转换成需要的对象
        SkuInfo skuInfo = BeanUtil.copyProperties(saveSkuDTO, SkuInfo.class);
        SkuDetail skuDetail = BeanUtil.copyProperties(saveSkuDTO, SkuDetail.class);
        // ========= 商品基本信息 ==========
        skuInfo.setCreateUser(admin.getUsername());
        skuInfo.setUpdateUser(admin.getUsername());
        // 上传单图至Minio
        if (saveSkuDTO.getSkuImg() != null && !saveSkuDTO.getSkuImg().isEmpty()) {
            String skuImg = minioService.uploadByFile(saveSkuDTO.getSkuImg());
            skuInfo.setSkuImg(skuImg);
        }
        skuInfoMapper.insert(skuInfo);
        // ========= 商品详情 ==========
        skuDetail.setSkuId(skuInfo.getId());
        skuDetail.setCreateUser(admin.getUsername());
        skuDetail.setUpdateUser(admin.getUsername());
        List<String> banner = new ArrayList<>();
        // 上传轮播图
        if (saveSkuDTO.getBanner() != null) {
            if (!saveSkuDTO.getBanner().isEmpty() && saveSkuDTO.getBanner().size() > 0) {
                saveSkuDTO.getBanner().forEach(item -> {
                    // 上传图片，返回访问地址，插入到数组中
                    String s = minioService.uploadByFile(item);
                    banner.add(s);
                });
                skuDetail.setBanner(JSON.toJSONString(banner));
            }
        }
        skuDetailMapper.insert(skuDetail);
    }

    /**
     * 根据ID获取商品信息
     * @param id
     * @return
     */
    @Override
    public SkuVO getSkuById(String id) {
        return skuInfoMapper.getSkuById(id);
    }

    /**
     * 根据ID列表 获取商品信息
     * @param ids
     * @return
     */
    @Override
    public List<SkuInfo> getSkuByIds(Collection<String> ids) {
        return skuInfoMapper.selectBatchIds(ids);
    }

    /**
     * 更新商品
     * @param updateSkuDTO
     */
    @Override
    public void updateSku(UpdateSkuDTO updateSkuDTO) {
        // 获取用户信息
        Admin admin = AuthContextUtil.get();
        if (StrUtil.isBlank(updateSkuDTO.getSkuId())) throw new ServiceException(ResultCodeEnum.PARAM_REQUIRE);
        // 处理数据，转换成需要的对象
        SkuInfo skuInfo = BeanUtil.copyProperties(updateSkuDTO, SkuInfo.class);
        SkuDetail skuDetail = BeanUtil.copyProperties(updateSkuDTO, SkuDetail.class);
        // ========= 商品基本信息 ==========
        skuInfo.setCreateUser(admin.getUsername());
        skuInfo.setUpdateUser(admin.getUsername());
        // 上传单图至Minio
        if (!updateSkuDTO.getNewSkuImg().isEmpty()) {
            // 删除旧图片
            minioService.removeFile(updateSkuDTO.getOldSkuImg());
            // 上传新图片
            String skuImg = minioService.uploadByFile(updateSkuDTO.getNewSkuImg());
            skuInfo.setSkuImg(skuImg);
        }
        skuInfoMapper.update(skuInfo, Wrappers.<SkuInfo>lambdaUpdate()
                .eq(SkuInfo::getId, updateSkuDTO.getSkuId()));
        // ========= 商品详情 ==========
        skuDetail.setCreateUser(admin.getUsername());
        skuDetail.setUpdateUser(admin.getUsername());
        List<String> banner = new ArrayList<>();
        // 上传轮播图
        if (!updateSkuDTO.getBanner().isEmpty() && updateSkuDTO.getBanner().size() > 0) {
            updateSkuDTO.getBanner().forEach(i -> {
                // 上传图片，返回访问地址，插入到数组中
                String s = minioService.uploadByFile(i);
                banner.add(s);
            });
            skuDetail.setBanner(JSON.toJSONString(banner));
        }
        // 删除旧的轮播图
        if (updateSkuDTO.getOldBanner() != null && updateSkuDTO.getOldBanner().size() > 0) {
            updateSkuDTO.getOldBanner().forEach(i -> minioService.removeFile(i));
        }
        skuDetailMapper.update(skuDetail, Wrappers.<SkuDetail>lambdaUpdate()
                .eq(SkuDetail::getSkuId, updateSkuDTO.getSkuId()));
    }

    /**
     * 根据商品ID修改商品售卖状态
     * @param skuId 商品ID
     * @param onSale 售卖状态
     */
    @Override
    public void updateSkuOnSaleById(String skuId, boolean onSale) {
        // 获取用户信息
//        Admin admin = AuthContextUtil.get();
        final Admin admin = new Admin();
        admin.setUsername("测试");
        int row = 0;
        if (!onSale) {
            // 商品上架
            row = skuInfoMapper.update(null, Wrappers.<SkuInfo>lambdaUpdate()
                    .set(SkuInfo::getOnSale, ProductConstant.SKU_ON_SALE)
                    .set(SkuInfo::getUpdateUser, admin.getUsername())
                    .eq(SkuInfo::getId, skuId));
            // 发送消息
            notifySaleUpdate(skuId, MQConst.GOODS_UPPER_KEY);
        } else  {
            // 商品下架
            row = skuInfoMapper.update(null, Wrappers.<SkuInfo>lambdaUpdate()
                    .set(SkuInfo::getOnSale, ProductConstant.SKU_UN_ON_SALE)
                    .set(SkuInfo::getUpdateUser, admin.getUsername())
                    .eq(SkuInfo::getId, skuId));
            notifySaleUpdate(skuId, MQConst.GOODS_LOWER_KEY);
        }
        if (row == 0) throw new ServiceException(ResultCodeEnum.DATA_NOT_EXIST);
    }

    /**
     * 根据ID逻辑删除商品数据
     * @param id
     */
    @Override
    public void removeSkuById(String id) {
        // 获取用户信息
        Admin admin = AuthContextUtil.get();
        // 根据商品ID拿到对应的数据
        SkuInfo skuInfo = skuInfoMapper.selectById(id);
        SkuDetail skuDetail = skuDetailMapper.selectOne(Wrappers.<SkuDetail>lambdaQuery()
                .eq(SkuDetail::getSkuId, id));
        if (skuInfo == null || skuDetail == null) throw new ServiceException(ResultCodeEnum.DATA_NOT_EXIST);
        // 删除图片和轮播图
        if (StrUtil.isNotBlank(skuInfo.getSkuImg())) {
            minioService.removeFile(skuInfo.getSkuImg());
        }
        if (StrUtil.isNotBlank(skuDetail.getBanner())) {
            List<String> banner = JSON.parseArray(skuDetail.getBanner(), String.class);
            if (banner.size() > 0) banner.forEach(i -> minioService.removeFile(i));
        }
        // 更新数据
        skuInfoMapper.update(null, Wrappers.<SkuInfo>lambdaUpdate()
                .set(SkuInfo::getUpdateUser, admin.getUsername())
                .set(SkuInfo::getIsDeleted, SQLConstant.DELETED)
                .eq(SkuInfo::getId, id));
        skuDetailMapper.update(null, Wrappers.<SkuDetail>lambdaUpdate()
                .set(SkuDetail::getUpdateUser, admin.getUsername())
                .set(SkuDetail::getIsDeleted, SQLConstant.DELETED)
                .eq(SkuDetail::getSkuId, id));
    }

    /**
     * 商品销售状态更新，发送消息
     * @param skuId 商品ID
     */
    @Override
    public void notifySaleUpdate(String skuId, String routingKey) {
        // 构建消息，且持久化
        Message message = MessageBuilder.withBody(skuId.getBytes(StandardCharsets.UTF_8))
                .setDeliveryMode(MessageDeliveryMode.PERSISTENT).build();
        rabbitService.sendMessage(MQConst.GOODS_DIRECT_EXCHANGE, routingKey, message);
    }

    /**
     * 根据关键字匹配sku列表
     * @param keyword 关键字
     * @return 商品列表信息
     */
    @Override
    public List<SkuInfo> findSkuInfoByKeyword(String keyword) {
        List<SkuInfo> skuInfoList = baseMapper.selectList(
                new LambdaQueryWrapper<SkuInfo>()
                        .like(SkuInfo::getSkuName, keyword)
        );
        return skuInfoList;
    }
}
